"""
缓存服务
用于缓存需求分析结果和测试用例生成结果，减少大模型调用次数
"""

import hashlib
import json
import time
from typing import Dict, Any, Optional
import logging

logger = logging.getLogger(__name__)


class CacheService:
    """缓存服务类"""
    
    def __init__(self, cache_ttl: int = 3600):  # 默认缓存1小时
        self.cache_ttl = cache_ttl
        self.requirement_analysis_cache: Dict[str, Dict[str, Any]] = {}
        self.test_case_cache: Dict[str, Dict[str, Any]] = {}
        
    def _generate_cache_key(self, content: str, prefix: str = "") -> str:
        """生成缓存键"""
        # 清理内容，移除多余空白字符
        cleaned_content = " ".join(content.strip().split())
        
        # 生成哈希值
        hash_obj = hashlib.md5(cleaned_content.encode('utf-8'))
        cache_key = f"{prefix}_{hash_obj.hexdigest()}"
        
        return cache_key
    
    def _is_cache_valid(self, cache_entry: Dict[str, Any]) -> bool:
        """检查缓存是否有效"""
        if not cache_entry:
            return False
            
        timestamp = cache_entry.get('timestamp', 0)
        current_time = time.time()
        
        return (current_time - timestamp) < self.cache_ttl
    
    def get_requirement_analysis(self, requirement: str) -> Optional[Dict[str, Any]]:
        """获取需求分析缓存"""
        try:
            cache_key = self._generate_cache_key(requirement, "req_analysis")
            cache_entry = self.requirement_analysis_cache.get(cache_key)
            
            if self._is_cache_valid(cache_entry):
                logger.info(f"需求分析缓存命中: {cache_key[:16]}...")
                return cache_entry['data']
            else:
                # 清理过期缓存
                if cache_entry:
                    del self.requirement_analysis_cache[cache_key]
                    logger.debug(f"清理过期的需求分析缓存: {cache_key[:16]}...")
                
                return None
                
        except Exception as e:
            logger.error(f"获取需求分析缓存失败: {e}")
            return None
    
    def set_requirement_analysis(self, requirement: str, analysis_result: Dict[str, Any]) -> None:
        """设置需求分析缓存"""
        try:
            cache_key = self._generate_cache_key(requirement, "req_analysis")
            
            cache_entry = {
                'data': analysis_result,
                'timestamp': time.time(),
                'requirement_length': len(requirement)
            }
            
            self.requirement_analysis_cache[cache_key] = cache_entry
            logger.info(f"需求分析结果已缓存: {cache_key[:16]}...")
            
            # 清理过期缓存（每次设置时检查）
            self._cleanup_expired_cache(self.requirement_analysis_cache)
            
        except Exception as e:
            logger.error(f"设置需求分析缓存失败: {e}")
    
    def get_test_cases(self, requirement: str, project_name: str = "", module_name: str = "") -> Optional[Dict[str, Any]]:
        """获取测试用例缓存"""
        try:
            # 组合缓存键内容
            cache_content = f"{requirement}|{project_name}|{module_name}"
            cache_key = self._generate_cache_key(cache_content, "test_cases")
            cache_entry = self.test_case_cache.get(cache_key)
            
            if self._is_cache_valid(cache_entry):
                logger.info(f"测试用例缓存命中: {cache_key[:16]}...")
                return cache_entry['data']
            else:
                # 清理过期缓存
                if cache_entry:
                    del self.test_case_cache[cache_key]
                    logger.debug(f"清理过期的测试用例缓存: {cache_key[:16]}...")
                
                return None
                
        except Exception as e:
            logger.error(f"获取测试用例缓存失败: {e}")
            return None
    
    def set_test_cases(self, requirement: str, test_cases_result: Dict[str, Any], 
                      project_name: str = "", module_name: str = "") -> None:
        """设置测试用例缓存"""
        try:
            # 组合缓存键内容
            cache_content = f"{requirement}|{project_name}|{module_name}"
            cache_key = self._generate_cache_key(cache_content, "test_cases")
            
            cache_entry = {
                'data': test_cases_result,
                'timestamp': time.time(),
                'requirement_length': len(requirement),
                'test_cases_count': len(test_cases_result.get('test_cases', []))
            }
            
            self.test_case_cache[cache_key] = cache_entry
            logger.info(f"测试用例结果已缓存: {cache_key[:16]}...")
            
            # 清理过期缓存
            self._cleanup_expired_cache(self.test_case_cache)
            
        except Exception as e:
            logger.error(f"设置测试用例缓存失败: {e}")
    
    def _cleanup_expired_cache(self, cache_dict: Dict[str, Dict[str, Any]]) -> None:
        """清理过期缓存"""
        try:
            current_time = time.time()
            expired_keys = []
            
            for key, entry in cache_dict.items():
                if (current_time - entry.get('timestamp', 0)) >= self.cache_ttl:
                    expired_keys.append(key)
            
            for key in expired_keys:
                del cache_dict[key]
            
            if expired_keys:
                logger.debug(f"清理了 {len(expired_keys)} 个过期缓存项")
                
        except Exception as e:
            logger.error(f"清理过期缓存失败: {e}")
    
    def clear_all_cache(self) -> None:
        """清空所有缓存"""
        try:
            req_count = len(self.requirement_analysis_cache)
            test_count = len(self.test_case_cache)
            
            self.requirement_analysis_cache.clear()
            self.test_case_cache.clear()
            
            logger.info(f"已清空所有缓存: 需求分析缓存 {req_count} 项, 测试用例缓存 {test_count} 项")
            
        except Exception as e:
            logger.error(f"清空缓存失败: {e}")
    
    def get_cache_stats(self) -> Dict[str, Any]:
        """获取缓存统计信息"""
        try:
            current_time = time.time()
            
            # 统计需求分析缓存
            req_total = len(self.requirement_analysis_cache)
            req_valid = sum(1 for entry in self.requirement_analysis_cache.values() 
                           if (current_time - entry.get('timestamp', 0)) < self.cache_ttl)
            
            # 统计测试用例缓存
            test_total = len(self.test_case_cache)
            test_valid = sum(1 for entry in self.test_case_cache.values() 
                            if (current_time - entry.get('timestamp', 0)) < self.cache_ttl)
            
            return {
                'requirement_analysis': {
                    'total': req_total,
                    'valid': req_valid,
                    'expired': req_total - req_valid
                },
                'test_cases': {
                    'total': test_total,
                    'valid': test_valid,
                    'expired': test_total - test_valid
                },
                'cache_ttl': self.cache_ttl
            }
            
        except Exception as e:
            logger.error(f"获取缓存统计失败: {e}")
            return {}
    
    def is_similar_requirement(self, requirement1: str, requirement2: str, similarity_threshold: float = 0.8) -> bool:
        """检查两个需求是否相似（简单实现）"""
        try:
            # 简单的相似度检查：基于词汇重叠
            words1 = set(requirement1.lower().split())
            words2 = set(requirement2.lower().split())
            
            if not words1 or not words2:
                return False
            
            intersection = words1.intersection(words2)
            union = words1.union(words2)
            
            similarity = len(intersection) / len(union) if union else 0
            
            return similarity >= similarity_threshold
            
        except Exception as e:
            logger.error(f"相似度检查失败: {e}")
            return False


# 全局缓存服务实例
_cache_service = None


def get_cache_service() -> CacheService:
    """获取缓存服务实例（单例模式）"""
    global _cache_service
    if _cache_service is None:
        _cache_service = CacheService()
    return _cache_service
